package com.shaozi.nc.quartz.attendance;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import com.shaozi.data.mq.business.base.MqConsts.UserType;
import com.shaozi.data.mq.business.utils.MqUtil;
import com.shaozi.data.mq.business.base.SourceTypeConsts;
import com.shaozi.data.mq.business.bean.MqTargetUserBean;
import com.shaozi.im.protocol.core.IMConsts;
import com.shaozi.lib.throwable.SzException;
import com.shaozi.nc.consts.VoConsts;
import com.shaozi.nc.data.hibVO.AttendanceVO;
import com.shaozi.nc.data.model.SecretaryModel;
import com.shaozi.nc.data.mongodao.SecretaryMDao;
import com.shaozi.nc.hibservice.AttendanceService;
import com.shaozi.nc.manage.secretary.SecretaryManage;
import com.shaozi.nc.mq.bean.attendance.SecretaryPunchExtraBean;
import com.shaozi.nc.quartz.QuartzJob;
import com.shaozi.nc.utils.SecretaryHelper;
import com.shaozi.utils.common.BeanUtils;
import com.shaozi.utils.common.ClassPathProperties;
import com.shaozi.utils.spel.SimpleEval;

public class AttendanceSignQuartzJob implements QuartzJob {

	private Logger logger = Logger.getLogger(AttendanceSignQuartzJob.class);
	private String title;
	private String incontent, outcontent;
	private String inStr;
	private String outStr;

	@Autowired
	private AttendanceService attendanceService;

	@Autowired
	private SecretaryMDao secretaryMDao;
	@Autowired
	private BeanUtils beanUtils;

	public AttendanceSignQuartzJob() {
		super();
	}

	public void init() {
		title = beanUtils.getConfig().getValue("push.msg.oa.attendance.title");
		incontent = beanUtils.getConfig().getValue("push.msg.oa.attendance.punch.in");
		outcontent = beanUtils.getConfig().getValue("push.msg.oa.attendance.punch.out");
		inStr = beanUtils.getConfig().getValue("push.msg.attendance.punch.in.str");
		outStr = beanUtils.getConfig().getValue("push.msg.attendance.punch.out.str");
	}

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		long levelId = getLevelId(context);
		if (levelId == -1) {
			logger.warn("考勤定时任务执行，levelId is -1");
			return;
		}
		String companyId = context.getJobDetail().getJobDataMap().getString("companyId");
		if (StringUtils.isEmpty(companyId)) {
			logger.warn("考勤定时任务执行，companyId is null");
			return;
		}
		int type = Integer.parseInt(context.getJobDetail().getJobDataMap().getString("type"));
		// 是否是观察者
		boolean isObserver = Boolean.parseBoolean(context.getJobDetail().getJobDataMap().getString("isObserver"));
		logger.info("companyId=" + companyId + ";levelId=" + levelId + ";job trigger" + ",isObserver:" + isObserver);
		String punchTime = context.getJobDetail().getJobDataMap().getString("punchTime");
		try {
			List<AttendanceVO> attendanceVOs = attendanceService.getTodayUnpunch(companyId, levelId, type);
			if (attendanceVOs.isEmpty()) {
				logger.warn("考勤定时任务执行, 查询 考情列表数据 查询今天未打卡的数据 为空 则不执行提醒任务，companyId:" + companyId + ",levelId:" + levelId
						+ ",type:" + type);
				return;
			}
			List<SecretaryModel> secretarys = getSecretaryModels(companyId, punchTime, attendanceVOs, isObserver);
			sendSecretary(companyId, secretarys);
		} catch (SzException e) {
			logger.error(SzException.getStackMessage(e));
		}
	}

	private void sendSecretary(String companyId, List<SecretaryModel> secretarys) throws SzException {

		SecretaryManage secretaryMgr = (SecretaryManage) BeanUtils.getBean("secretaryMgr");
		secretaryMgr.handleByPushType(companyId, secretarys);
	}

	private List<SecretaryModel> getSecretaryModels(String companyId, String punchTime,
			List<AttendanceVO> attendanceVOs, boolean isObserver) {
		List<SecretaryModel> ret = new ArrayList<>();
		SimpleEval eval = new SimpleEval();

		attendanceVOs.forEach((model) -> {
			int sourceType = attendanceTypeToSourceType(model.getType());
			if (sourceType != SourceTypeConsts.Undefine) {
				Integer extraId = model.getId();
				String userId = String.valueOf(model.getUid());
				if (isObserver) {
					try {
						SecretaryModel isSendSecretaryAttendance = secretaryMDao.findByExtraId(companyId, userId,
								extraId, sourceType);
						// 表示已经发送过的数据
						if (isSendSecretaryAttendance != null) {
							logger.info("已经发送过小秘书了不需要再次发送,companyId:" + companyId + ",userId" + userId + ",extraId"
									+ extraId + ",sourceType:" + sourceType);
							return;
						}
					} catch (SzException e) {
						logger.error(e.getMessage(), e);
					}
				}

				List<MqTargetUserBean> users = new ArrayList<>();
				MqTargetUserBean user = new MqTargetUserBean(userId);
				users.add(user);

				SecretaryModel secretary = new SecretaryModel();
				secretary.setSourceType(sourceType);
				secretary.setPushType(SecretaryModel.PushType_Need_Save);
				secretary.setUsers(users);
				secretary.setCompanyId(companyId);
				secretary.setTriggerUserId(String.valueOf(IMConsts.SysMemberId.Secretary_Id));
				secretary.setFromUserId(String.valueOf(IMConsts.SysMemberId.Secretary_Id));
				SecretaryPunchExtraBean extra = new SecretaryPunchExtraBean();
				extra.setPunchTime(punchTimeToMillis(punchTime));
				secretary.setTitle(title);
				Map<String, Object> params = new HashMap<>();
				params.put("inout", punchTypeString(sourceType));
				params.put("inoutTime", formatPrintPunchTime(punchTime));
				String c = "";
				if (model.getType() == VoConsts.Attendance.Type_In)
					c = incontent;
				else
					c = outcontent;
				c = (String) eval.eval(c, params);
				secretary.setContent(c);
				secretary.setType(MqUtil.getBaseSourceType(sourceType));
				secretary.setNotifyType(SecretaryHelper.getNotifyTypeFromSourceType(sourceType, UserType.Undefine));
				extra.setId(extraId);
				secretary.setExtra(extra.toJsonString());
				secretary.setExtraBean(extra);
				secretary.setSound(this.getSound());
				ret.add(secretary);
			}
		});

		return ret;
	}

	private String getSound() {
		String clock = BeanUtils.getConfig().getPropertySourceValue("send.sound.nc.clock", "clock");
		String wav = BeanUtils.getConfig().getPropertySourceValue("send.sound.suffix", "wav");
		return clock + "." + wav;
	}

	private String formatPrintPunchTime(String punchTime) {
		String[] hm = punchTime.split(":");
		return String.format("%s:%s", hm[0], hm[1]);
	}

	/**
	 * 
	 * @param punchTime
	 *            09:00:00 / 09:00
	 * @return
	 */
	private long punchTimeToMillis(String punchTime) {
		String[] hm = punchTime.split(":");
		int h = Integer.valueOf(hm[0]);
		int m = Integer.valueOf(hm[1]);
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, h);
		cal.set(Calendar.MINUTE, m);
		return cal.getTimeInMillis();
	}

	private String punchTypeString(int sourceType) {
		switch (sourceType) {
		case SourceTypeConsts.OA.Attendance.Punch_In:
			return inStr;

		case SourceTypeConsts.OA.Attendance.Punch_Out:
			return outStr;
		default:
			break;
		}
		return "";
	}

	/**
	 * 
	 * @param type
	 *            0未知 1签到 2签退
	 * @return
	 */
	private int attendanceTypeToSourceType(int type) {
		if (type == VoConsts.Attendance.Type_In)
			return SourceTypeConsts.OA.Attendance.Punch_In;
		else if (type == VoConsts.Attendance.Type_Out)
			return SourceTypeConsts.OA.Attendance.Punch_Out;
		else
			return SourceTypeConsts.Undefine;
	}

	private long getLevelId(JobExecutionContext context) {
		JobKey key = context.getJobDetail().getKey();
		if (StringUtils.isEmpty(key.getName()))
			return -1l;
		String levelId = context.getJobDetail().getJobDataMap().getString("levelId");
		try {
			return Long.parseLong(levelId);
		} catch (NumberFormatException e) {
			return -1l;
		}
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getInStr() {
		return inStr;
	}

	public void setInStr(String inStr) {
		this.inStr = inStr;
	}

	public String getOutStr() {
		return outStr;
	}

	public void setOutStr(String outStr) {
		this.outStr = outStr;
	}

}
